package org.teamh.gui.lobby;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.teamh.logic.lobby.Player;
import org.teamh.logic.lobby.Team;

import de.lessvoid.nifty.builder.ImageBuilder;
import de.lessvoid.nifty.builder.PanelBuilder;
import de.lessvoid.nifty.builder.TextBuilder;
import de.lessvoid.nifty.controls.TextField;
import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.elements.render.ImageRenderer;
import de.lessvoid.nifty.elements.render.TextRenderer;
import de.lessvoid.nifty.render.NiftyImage;
import de.lessvoid.nifty.tools.Color;

public class PlayerBoxController {
	
	private NiftyImage plusImage;
	private NiftyImage minusImage;
	private ArrayList<Team> playerInTeam;
	private LobbyController lobbyController;
	private String redMarked;
	private List<Player> oldList;
	
	public PlayerBoxController(LobbyController lobbyController) {
		this.lobbyController = lobbyController;
		plusImage = lobbyController.getNifty().getRenderEngine().createImage("res/img/lobby/plus.png",
				false);
		minusImage = lobbyController.getNifty().getRenderEngine().createImage("res/img/lobby/minus.png",
				false);
		playerInTeam = new ArrayList<Team>();
	}

	public void updatePlayerInTeamList(LinkedList<Player> newPlayerList) {
		if(oldList == null) {
			oldList = new ArrayList<Player>();
		}
		checkNewList(newPlayerList);
	}

	private void checkNewList(LinkedList<Player> newPlayerList) {
		boolean isIn = false;
		for(int i = 0; i < newPlayerList.size(); i++) {
			for(int j = 0; j < oldList.size(); j++) {
				if(oldList.get(j).getName().equals(newPlayerList.get(i).getName())) {
					if(oldList.get(j).getTeam().equals(newPlayerList.get(i).getTeam())) {
						isIn = true;
					}
				} 
			}
			if(!isIn) {
				oldList.add(newPlayerList.get(i));
				checkAdd(newPlayerList.get(i));
			}
			isIn = false;
		}
		isIn = false;
		for(int i = 0; i < oldList.size(); i++) {
			for(int j = 0; j < newPlayerList.size(); j++) {
				if(newPlayerList.get(j).getName().equals(oldList.get(i).getName())) {
					if(newPlayerList.get(j).getTeam().equals(oldList.get(i).getTeam())) {
						isIn = true;
					}
				} 
			}
			if(!isIn) {
				checkDelete(oldList.get(i));
				oldList.remove(oldList.get(i));
			}
			isIn = false;
		}
	}

	private void checkDelete(Player player) {
		int index = findTeamIndexOfPlayer(player.getTeam());
		ImageRenderer img = lobbyController.getPlayerBox().findElementByName("icon " + player.getTeam()).getRenderer(ImageRenderer.class);
		int cnt	= playerInTeam.get(index).getPlayers().size();
		if(img.getImage() == minusImage) {
			if(cnt == 1) {
				deletePlayer(player.getTeam(), player.getName());
				deleteTeam(player.getTeam());
				playerInTeam.remove(index);
				if(player.getName().equals(redMarked) || player.getTeam().equals(redMarked)) {
					redMarked = null;
				}
			} else {
				deletePlayer(player.getTeam(), player.getName());
				playerInTeam.get(index).removePlayer(player.getName());
				if(player.getName().equals(redMarked)) {
					redMarked = null;
				}
			}
		} else {
			if(cnt == 1) {
				deleteTeam(player.getTeam());
				playerInTeam.remove(index);
				if(player.getTeam().equals(redMarked)) {
					redMarked = null;
				}
			} else {
				playerInTeam.get(index).removePlayer(player.getName());
				if(player.getName().equals(redMarked)) {
					redMarked = null;
				}
			}
		}
	}

	private int findTeamIndexOfPlayer(String name) {
		int index = 0;
		for (Team t : playerInTeam) {
			if (t.getTeamName().equals(name)) {
				index = playerInTeam.indexOf(t);
			}
		}
		return index;
	}

	private void deleteTeam(String team) {
		Element toDel = lobbyController.getPlayerBox().findElementByName("id " + team);
		toDel.markForRemoval();
		lobbyController.getPlayerBox().getElements().remove("id " + team);
	}

	private void deletePlayer(String team, String name) {
		Element toDel = lobbyController.getPlayerBox().findElementByName("id " + name);
		toDel.markForRemoval();
		lobbyController.getPlayerBox().findElementByName(team).getElements().remove("id " + name);
	}
	
	

	private void checkAdd(Player player) {
		if(lobbyController.getPlayerBox().findElementByName(player.getTeam()) == null) {
			addTeam(player.getTeam());
			playerInTeam.add(new Team(player.getTeam(), player.getName()));
		} else {
			ImageRenderer img = lobbyController.getScreen().findElementByName("icon " + player.getTeam()).getRenderer(ImageRenderer.class);
			if(img.getImage() == minusImage) {
				addPlayerToTeam(player.getTeam(), player.getName());
			}
			int cnt = findTeamIndexOfPlayer(player.getTeam());
			playerInTeam.get(cnt).addPlayer(player.getName());
		}
	}

	private void addPlayerToTeam(String teamName, String playerName) {
		final String name = playerName;
		Element teamPanel = lobbyController.getPlayerBox().findElementByName("filler " + teamName);
		PanelBuilder panel = new PanelBuilder("id " + name) {
			{
				childLayoutHorizontal();
				height("20px");
				panel(new PanelBuilder() {
					{
						width("50px");
					}
				});

				text(new TextBuilder(name) {
					{
						text(name);
						font("aurulent-sans-16.fnt");
						interactOnClick("fillMessageBoxWithName("
								+ name + ")");
					}
				});
			}
		};

		teamPanel.add(panel.build(lobbyController.getNifty(), lobbyController.getScreen(), teamPanel));
		removeDuplicates(teamPanel.getElements());
		
	}

	public void fillPlayerBox() {
		for (Team t : playerInTeam) {
			String name = t.getTeamName();
			addTeam(name);
		}
	}
	
	private void addTeam(String teamName) {
		final String name = teamName;
		if (lobbyController.getPlayerBox().findElementByName(name) == null) {

			PanelBuilder panel = new PanelBuilder("id " + name) {
				{
					childLayoutVertical();
					panel(new PanelBuilder() {
						{
							height("5px");
						}
					});
					panel(new PanelBuilder() {
						{
							childLayoutHorizontal();
							height("20px");
							panel(new PanelBuilder() {
								{
									width("10px");
								}
							});
							image(new ImageBuilder("icon " + name) {
								{
									filename("res/img/lobby/plus.png");
									alignCenter();
									interactOnClick("showTeamMember("
											+ name + ")");
								}
							});
							panel(new PanelBuilder() {
								{
									width("5px");
								}
							});
							text(new TextBuilder(name) {
								{
									text(name);
									font("aurulent-sans-16.fnt");
									interactOnClick("fillMessageBoxWithName("
											+ name + ")");
								}
							});
						}
					});
					panel(new PanelBuilder("filler " + name) {
						{
							childLayoutVertical();
							
						}
					});
				}
			};

			lobbyController.getPlayerBox().add(panel.build(lobbyController.getNifty(), lobbyController.getScreen(), lobbyController.getPlayerBox()));
		}
		removeDuplicates(lobbyController.getPlayerBox().getElements());
	}
	
	public void removeDuplicates(List<Element> list) {
		int index = 0;
		while (index < list.size() - 1) {
			Element c1 = list.get(index);
			Element c2 = list.get(index + 1);
			if (c1.equals(c2)) {
				list.remove(index + 1);
			} else {
				index++;
			}
		}
	}

	public void showTeamMember(String name) {
		ImageRenderer renderer = lobbyController.getScreen().findElementByName("icon " + name)
				.getRenderer(ImageRenderer.class);
		if (renderer.getImage() == minusImage) {
			renderer.setImage(plusImage);
			Element teamPanel = lobbyController.getScreen().findElementByName(
					"filler " + name);
			
			for (Element child : teamPanel.getElements()) { 
				child.markForRemoval(); 
			}
		} else {
			renderer.setImage(minusImage);

			int cnt = findTeamIndexOfPlayer(name);
			for (String p : playerInTeam.get(cnt).getPlayers()) {
				addPlayerToTeam(name, p);
			}
		}
	}

	public void fillMessageBoxWithName(String name) {
		TextRenderer renderer;
		TextField textField = lobbyController.getScreen().findNiftyControl("chatMessagesField", TextField.class);
		if(redMarked == null) {
			redMarked = name;
			renderer = lobbyController.getScreen().findElementByName(name)
			.getRenderer(TextRenderer.class);
			renderer.setColor(new Color(1, 0, 0, 1));
			
			textField.setText("@" + name + " ");
			textField.setCursorPosition(textField.getText().length());
		} else {
			if(redMarked.equals(name)) {
				renderer = lobbyController.getScreen().findElementByName(redMarked)
				.getRenderer(TextRenderer.class);
				renderer.setColor(new Color(1, 1, 1, 1));
				redMarked = null;
				
				textField.setText("");
			} else {
				renderer = lobbyController.getScreen().findElementByName(redMarked)
				.getRenderer(TextRenderer.class);
				renderer.setColor(new Color(1, 1, 1, 1));
				renderer = lobbyController.getScreen().findElementByName(name)
				.getRenderer(TextRenderer.class);
				renderer.setColor(new Color(1, 0, 0, 1));
				redMarked = name;
				
				textField.setText("@" + name + " ");
				textField.setCursorPosition(textField.getText().length());
			}
		}
		
	}

	public ArrayList<Team> getPlayerInTeam() {
		return playerInTeam;
	}
	
	public String getRedMarked() {
		return redMarked;
	}

	public void setRedMarked(String name) {
		redMarked = name;
	}

	public void deleteAll() {
		for (Element child : lobbyController.getPlayerBox().getElements()) { 
			child.markForRemoval(); 
		}
		getPlayerInTeam().clear();
		setRedMarked(null);
		oldList.clear();
	}

	public void clearColor() {
		TextRenderer renderer;
		renderer = lobbyController.getScreen().findElementByName(redMarked)
		.getRenderer(TextRenderer.class);
		renderer.setColor(new Color(1, 1, 1, 1));
		redMarked = null;
	}
}
